<?php


namespace app\api\service;


use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\api\service\Token as TokenService;
use app\common\enum\OrderStatusEnum;
use app\common\exception\OrderException;
use app\common\exception\TokenException;
use app\common\wechat\pay\WxPayConfig;
use think\Config;
use think\Exception;
use think\Loader;
use think\Log;

// extend/wechat/WxPay.Api.php
Loader::import('wechat.WxPay', EXTEND_PATH, '.Api.php');

class Pay
{
    protected $order_id;
    protected $order_no;
    private $wx_pay_config;

    public function __construct($order_id)
    {
        //数值类型检测，没有检测业务
        if(!$order_id){
            throw new Exception('订单号不允许为null');
        }
        $this->order_id = $order_id;
        $this->getWxPayConfig();
    }

    public function pay()
    {
        //检测订单状态
        $this->checkOrderValid($this->order_id);
        //此时$this->order_no有值了
        //4.检测库存量状态
        $order_service = new OrderService();
        $status = $order_service->checkOrderStatus($this->order_id);
        if (!$status['pass']) {
            return $status;
        }
//        return $this->makeWeChatPreOrder($status['total_price']);
        return $this->makeWeChatPreOrder($this->total_price);
    }

    private function makeWeChatPreOrder($total_price)
    {
//        $openid = 'oY_2u4lqsrliv72cX9P0gCVrjvbk';
        $openid = TokenService::getCurrentTokenVar('openid');
        if(!$openid)
        {
            throw new TokenException();
        }
        $wx_order_data = new \WxPayUnifiedOrder();
        $wx_order_data->SetOut_trade_no($this->order_no);
        $wx_order_data->SetTrade_type('JSAPI');
        $wx_order_data->SetTotal_fee($total_price * 100); //微信用费单位是分
        $wx_order_data->SetBody('齐家名录');
        $wx_order_data->SetOpenid($openid);
        $wx_order_data->SetNotify_url($this->wx_pay_config->GetNotifyUrl());
        return $this->getPaySignature($wx_order_data);
    }

    private function getPaySignature($wx_order_data)
    {
        /**
         *{
         * "return_code": "FAIL",
         * "return_msg": "invalid notify_url"
         * }
         *
         * {
        "appid": "wxd7a5ff580dd837c5",
        "mch_id": "1528016531",
        "nonce_str": "k6ljPBi6532lyoIX",
        "prepay_id": "wx20100742581258d1a1880d461452243500",
        "result_code": "SUCCESS",
        "return_code": "SUCCESS",
        "return_msg": "OK",
        "sign": "240961F4448F94DD50A77B208ECC5192CD88AD874DDAB8C0225C7DEC57B7199B",
        "trade_type": "JSAPI"
        }
         */
        $wx_order = \WxPayApi::unifiedOrder($this->wx_pay_config, $wx_order_data);
        if($wx_order['return_code'] != 'SUCCESS' || $wx_order['return_msg'] != 'OK'|| $wx_order['result_code'] == 'FAIL' )
        {
            Log::record($wx_order, 'error');
            Log::record('从微信服务器获取预订单失败', 'error');
            throw new OrderException([
                'http_code'=>400,
                'msg'=>'获取预支付订单失败',
            ]);
        }

        //记录prepay_id
        $this->recordPreOrder($wx_order);
        $signature = $this->sign($wx_order);

        return $signature;
    }

    private function sign($wx_order)
    {
        $js_api_data = new \WxPayJsApiPay();
        $js_api_data->SetAppid($this->wx_pay_config->GetAppId());
        $js_api_data->SetTimeStamp((string)time());

        $rand = md5(time() . mt_rand(0,1000));
        $js_api_data->SetNonceStr($rand);
        $js_api_data->SetPackage('prepay_id='.$wx_order['prepay_id']);
        $js_api_data->SetSignType('md5');

        $sign = $js_api_data->MakeSign($this->wx_pay_config);
        $rawValues = $js_api_data->GetValues();
        $rawValues['paySign'] = $sign;

        unset($rawValues['appId']);
        return $rawValues;
    }

    private function recordPreOrder($wx_order)
    {
        OrderModel::update(['id'=>$this->order_id, 'prepay_id'=>$wx_order['prepay_id']]);
//        OrderModel::isUpdate(true)
//            ->where('id', '=', $this->order_id)
//            ->update(['prepay_id'=>$wx_order['prepay_id']]);
    }

    //返回true的话，说明$this->order_no被设置成功
    private function checkOrderValid($order_id)
    {
        //这个检测流程要记住
        //1.订单号不存在
        //2.订单号存在，但不是当前用户的订单
        //3.订单有可能被支付了
        $order = OrderModel::where('id', '=', $order_id)->find();
        if(empty($order))
        {
            throw new OrderException();
        }

        if(!TokenService::isValidOperate($order->user_id)){
            throw new TokenException([
                'msg' => '当前用户操作的订单不是自己的哦',
                'code' => 10003
            ]);
        }

        if($order->status != OrderStatusEnum::UNPAID)
        {
            throw new OrderException([
                'http_code' => 400,
                'msg' => '订单已经被支付过了',
                'code' => 80003,
            ]);
        }
        $this->total_price = $order->total_price;
        $this->order_no = $order->order_no;
        return true;
    }

    private function getWxPayConfig()
    {
        $config = new WxPayConfig();
        $config->SetAppId(Config::get('wechat.app_id'));
        $config->SetAppSecret(Config::get('wechat.app_secret'));
        $config->SetMerchantId(Config::get('wechat.merchant_id'));
        $config->SetKey(Config::get('wechat.key'));
        $config->SetNotifyUrl(Config::get('wechat.notify_url'));
        $this->wx_pay_config = $config;
        return $this;
    }
}